package brandescm.bluetooth232;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


public class Main extends Activity 
{
	// Debugging
	private static final String TAG = "Bluetooth 232";
    private static final boolean D = true;
    
	public BluetoothAdapter mBluetoothAdapter = null;
	public final int REQUEST_ENABLE_BT = 2; //Defines callback value
    /** Called when the activity is first created. */
	TelephonyManager tManager;
	UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
	UUID testUUID = null;
	ListView Data;// = (ListView)findViewById(R.id.commsDataTextView);
	ModbusRTUMaster rtuOne;
	TextView bluetoothState_Text; // = (TextView)findViewById(R.id.BluetoothState);
	ArrayList<String> pairedList = new ArrayList<String>();
	ArrayList<String> uuidList = new ArrayList<String>();
	String selectedDevice = "";// selected paired device use to create socket
	private String deviceAddress = "0";
	private String value = "0";
	private String register = "0";
	BluetoothSocket bs;
	
	@Override
    public void onCreate(Bundle savedInstanceState) 
	{
        super.onCreate(savedInstanceState);
        if(D) Log.e(TAG, "+++ ON CREATE +++");
        
        setContentView(R.layout.main);
        tManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
        bluetoothState_Text = (TextView)findViewById(R.id.BluetoothState_TextBox);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        
        Data = (ListView)findViewById(R.id.commsData_TextView);
        Data.setOnItemClickListener(new OnItemClickListener() 
    	{    
    		public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
    		{ // When clicked, write selected device to DeviceID textview      
    			selectedDevice = (String)((TextView) view).getText();
    			writeDeviceID(selectedDevice);
    			pairedList.clear();	
    			try 
    			{
					PairedDeviceSelected(selectedDevice);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
    		}  
    	});  
        
        final EditText address_Text = (EditText)findViewById(R.id.deviceAddress_TextBox);
        address_Text.setOnFocusChangeListener(new View.OnFocusChangeListener() 
        {
			
			@Override
			public void onFocusChange(View v, boolean state) 
			{
				if (state)
					address_Text.selectAll();
				else 
				{
					deviceAddress = address_Text.getText().toString();
					
				}		
			}
		});
        
        final EditText value_Text = (EditText)findViewById(R.id.deviceValue_TextBox);
        value_Text.setOnFocusChangeListener(new View.OnFocusChangeListener() 
        {
			
			@Override
			public void onFocusChange(View v, boolean state) 
			{
				if (state)
					value_Text.selectAll();
				else 
				{
					value = value_Text.getText().toString();
				}		
			}
		});
        
        final EditText register_Text = (EditText)findViewById(R.id.deviceRegister_TextBox);
        register_Text.setOnFocusChangeListener(new View.OnFocusChangeListener() 
        {
			
			@Override
			public void onFocusChange(View v, boolean state) 
			{
				if (state)
					register_Text.selectAll();
				else 
				{
					register = register_Text.getText().toString();
				}		
			}
		});
        
    }
	public void PairedDeviceSelected(String pairedDevice) throws IOException
	{
		
		int start = pairedDevice.length() - 17;
		String macAddress = pairedDevice.substring(start);
		
		try{
			BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);	
			bs = device.createRfcommSocketToServiceRecord(uuid);
			bs.connect();
		}
		catch(IOException e){
			return;
		}
	}
	@Override
    public void onStart() 
	{
        super.onStart();
        
        if(D) Log.e(TAG, "++ ON START ++");
        bluetoothStartUp(); 
        testUUID = UUID.randomUUID();
        uuidList.add(testUUID.toString()); 
    }
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu)
	{
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.options_menu, menu);
    	
    	return true;
    }
	@Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
		super.onOptionsItemSelected(item);
   	 switch(item.getItemId())
   	 {
   	 	case R.id.searchForPairedDevicesMenu:
   	 	{
	   	 	Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
	    	// If there are paired devices
	    	if (pairedDevices.size() > 0) 
	    	{ // Loop through paired devices    
	    		for (BluetoothDevice device : pairedDevices) 
	    		{ // Add the name and address to an array adapter to show in a ListView        
	    			pairedList.add(device.getName() + "\n" + device.getAddress());
	    		}
	    		
	    		Data.setAdapter(new ArrayAdapter<String>(this, 
	    			android.R.layout.simple_list_item_single_choice, pairedList));            
	        }
   	 		return true;
   	 	}
   	 	
	   	 case R.id.discoveryMenu:
		 	{
		 		Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
		 		discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
		 		startActivity(discoverableIntent);
		 		mBluetoothAdapter.startDiscovery();
		   	    AcceptThread connect = new AcceptThread();
		   	    connect.start();
		 		return true;
		 	}
	   	 case R.id.exitMenu:
	   	 {
	   		mBluetoothAdapter.disable();
	    	finish();
	   	 }
   	 	default:
   	 		return super.onOptionsItemSelected(item);
   	 }
    }
	
	BroadcastReceiver bluetooth = new BroadcastReceiver()
	{
		@Override
		public void onReceive(Context context, Intent intent)
		{
			//String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE;
			String stateExtra = BluetoothAdapter.EXTRA_STATE;
			int state = intent.getIntExtra(stateExtra, -1);
			//int previousState = intent.getIntExtra(prevStateExtra, -1);
			
			//String tt = "";
			switch (state)
			{
				case (BluetoothAdapter.STATE_TURNING_ON) :
				{
					bluetoothState_Text.setTextColor(Color.GREEN);
					bluetoothState_Text.setText(R.string.Bluetooth_State_Turning_On);
					break;
				}
				case (BluetoothAdapter.STATE_ON):
				{
					bluetoothState_Text.setTextColor(Color.GREEN);
					bluetoothState_Text.setText(R.string.Bluetooth_State_On);
					//unregisterReceiver(this);
					break;
				}
				case (BluetoothAdapter.STATE_TURNING_OFF):
				{
					bluetoothState_Text.setTextColor(Color.YELLOW);
					bluetoothState_Text.setText(R.string.Bluetooth_State_Turning_Off); 
					//unregisterReceiver(this);
					break;
				}
				default: break;
			}
		}
			//Toast.makeText(context, tt, Toast.LENGTH_LONG).show();
	};
	 
	
	private void bluetoothStartUp()
    {
		if (!mBluetoothAdapter.isEnabled())
		{
			String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED;
			String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE;
			registerReceiver(bluetooth, new IntentFilter(actionStateChanged));
			startActivityForResult(new Intent(actionRequestEnable), 0);
		}
		else
		{
			bluetoothState_Text.setTextColor(Color.GREEN);
			bluetoothState_Text.setText(R.string.Bluetooth_State_On);
		}

    }
	public void bluetoothID_Click(View v)
	{
		TextView id = (TextView)findViewById(R.id.bluetoothID_TextBox);
		id.setText(mBluetoothAdapter.getName());
		//onFocusChange(address_Text, true);
	}
	
    public void sendButton_Click(View v)
    {
    	String commsPacketString = "";
    	ArrayList<Short> commsPacket = new ArrayList<Short>();
    	short NumberOfRegisters = 1;
    	rtuOne = new ModbusRTUMaster();
    	short DeviceAddress = 0x00;
    	DeviceAddress = Short.valueOf(deviceAddress);
    	short Value = Short.valueOf(value);
    	short Register = Short.valueOf(register);
    	commsPacket = rtuOne.ModbusRtuMaster_Write(DeviceAddress, Register, NumberOfRegisters, Value);
    	
    	for(short a : commsPacket)
    	{
    		commsPacketString += String.valueOf(a);
    	}
    	writeCommsData(commsPacketString);
    }
    public void closeButton_Click(View v)
    {
    	mBluetoothAdapter.disable();
    	finish();    	
    }
    public void writeCommsData(String data)
    {
    	OutputStream outStream;
    	pairedList.add(data);
    	Data.setAdapter(new ArrayAdapter<String>(this, 
    			android.R.layout.simple_list_item_1 , pairedList));
    	try
    	{
    		outStream = bs.getOutputStream();
    		
    		//Convert string to byte[]
    		byte[] byteArray = data.getBytes();
    		byteArray[byteArray.length - 1] = 0;
    		
    		outStream.write(byteArray);
    	}
    	catch (IOException e){}
    	//TextView commsData = (TextView)findViewById(R.id.commsData_TextView);
    	
    	//commsData.setText(data);// + "\r\n");
    }
    
    public void writeDeviceID(String deviceID)
    {
    	TextView id = (TextView)findViewById(R.id.bluetoothID_TextBox);
    	//String deviceID = mBluetoothAdapter.getName();
    	id.setText(deviceID);
    }
    
 // ==================================================================
	// FUNCTION:	  GatewayManager_ErrorHandler
	//
	// DESCRIPTION: This function displays error message.
	//
	// INPUTS:		  None
	// 
	// OUTPUTS:		  None
	// 
	// RETURNS:		  None
	// ------------------------------------------------------------------
	public void GatewayManager_ErrorHandler(ModbusRTUMaster error)
	{
		String message = error.getError();
		Context context = getApplicationContext();
		Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
		toast.show();
		
	}
	
	private class AcceptThread extends Thread 
	{    
		private final BluetoothServerSocket mmServerSocket;    
		public AcceptThread() 
		{ // Use a temporary object that is later assigned to mmServerSocket,        
		  // because mmServerSocket is final        
			BluetoothServerSocket tmp = null;        
			try 
			{// MY_UUID is the app's UUID string, also used by the client code            
				tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(selectedDevice, testUUID);        
			} 
			catch (IOException e) 
			{ 
				
			}        
			mmServerSocket = tmp;    
		}    
		public void run() 
		{        
			BluetoothSocket socket = null; 
			// Keep listening until exception occurs or a socket is returned        
			while (true) 
			{            
				try 
				{                
					socket = mmServerSocket.accept();            
				} 
				catch (IOException e) 
				{                
					break;            
				} // If a connection was accepted            
				if (socket != null) 
				{ // Do work to manage the connection (in a separate thread)                
					//manageConnectedSocket(socket);                
					//mmServerSocket.close();                
					break;            
				}        
			}    
		}    /** Will cancel the listening socket, and cause the thread to finish */    
		@SuppressWarnings("unused")
		public void cancel() 
		{        
			try 
			{            
				mmServerSocket.close();        
			} 
			catch (IOException e) 
			{ 
				
			}    
		}
				
	}
			
}	
	
